home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / sndhrdw / gottlieb.c < prev    next >
C/C++ Source or Header  |  2000-04-23  |  7KB  |  337 lines

  1. #include "driver.h"
  2. #include "cpu/m6502/m6502.h"
  3.  
  4.  
  5.  
  6.  
  7. WRITE_HANDLER( gottlieb_sh_w )
  8. {
  9.     static int score_sample=7;
  10.     static int random_offset=0;
  11.     data &= 0x3f;
  12.  
  13.     if ((data&0x0f) != 0xf) /* interrupt trigered by four low bits (not all 1's) */
  14.     {
  15.         if (Machine->samples)
  16.         {
  17.             if (!strcmp(Machine->gamedrv->name,"reactor"))    /* reactor */
  18.             {
  19.                 switch (data ^ 0x3f)
  20.                 {
  21.                     case 53:
  22.                     case 54:
  23.                     case 55:
  24.                     case 56:
  25.                     case 57:
  26.                     case 58:
  27.                     case 59:
  28.                         sample_start(0,(data^0x3f)-53,0);
  29.                         break;
  30.                     case 31:
  31.                         sample_start(0,7,0);
  32.                         score_sample=7;
  33.                         break;
  34.                     case 39:
  35.                         score_sample++;
  36.                         if (score_sample<20) sample_start(0,score_sample,0);
  37.                         break;
  38.                 }
  39.             }
  40.             else    /* qbert */
  41.             {
  42.                 switch (data ^ 0x3f)
  43.                 {
  44.                     case 17:
  45.                     case 18:
  46.                     case 19:
  47.                     case 20:
  48.                     case 21:
  49.                         sample_start(0,((data^0x3f)-17)*8+random_offset,0);
  50.                         random_offset= (random_offset+1)&7;
  51.                         break;
  52.                     case 22:
  53.                         sample_start(0,40,0);
  54.                         break;
  55.                     case 23:
  56.                         sample_start(0,41,0);
  57.                         break;
  58.                     case 28:
  59.                         sample_start(0,42,0);
  60.                         break;
  61.                     case 36:
  62.                         sample_start(0,43,0);
  63.                         break;
  64.                 }
  65.             }
  66.         }
  67.  
  68.         soundlatch_w(offset,data);
  69.  
  70.         switch (cpu_gettotalcpu())
  71.         {
  72.         case 2:
  73.             /* Revision 1 sound board */
  74.             cpu_cause_interrupt(1,M6502_INT_IRQ);
  75.             break;
  76.         case 3:
  77.         case 4:
  78.             /* Revision 2 & 3 sound board */
  79.             cpu_cause_interrupt(cpu_gettotalcpu()-1,M6502_INT_IRQ);
  80.             cpu_cause_interrupt(cpu_gettotalcpu()-2,M6502_INT_IRQ);
  81.             break;
  82.         }
  83.     }
  84. }
  85.  
  86.  
  87. void gottlieb_knocker(void)
  88. {
  89.     if (Machine->samples)
  90.     {
  91.         if (!strcmp(Machine->gamedrv->name,"reactor"))    /* reactor */
  92.         {
  93.         }
  94.         else    /* qbert */
  95.             sample_start(0,44,0);
  96.     }
  97. }
  98.  
  99. /* callback for the timer */
  100. void gottlieb_nmi_generate(int param)
  101. {
  102.     cpu_cause_interrupt(1,M6502_INT_NMI);
  103. }
  104.  
  105. static const char *PhonemeTable[65] =
  106. {
  107.  "EH3","EH2","EH1","PA0","DT" ,"A1" ,"A2" ,"ZH",
  108.  "AH2","I3" ,"I2" ,"I1" ,"M"  ,"N"  ,"B"  ,"V",
  109.  "CH" ,"SH" ,"Z"  ,"AW1","NG" ,"AH1","OO1","OO",
  110.  "L"  ,"K"  ,"J"  ,"H"  ,"G"  ,"F"  ,"D"  ,"S",
  111.  "A"  ,"AY" ,"Y1" ,"UH3","AH" ,"P"  ,"O"  ,"I",
  112.  "U"  ,"Y"  ,"T"  ,"R"  ,"E"  ,"W"  ,"AE" ,"AE1",
  113.  "AW2","UH2","UH1","UH" ,"O2" ,"O1" ,"IU" ,"U1",
  114.  "THV","TH" ,"ER" ,"EH" ,"E1" ,"AW" ,"PA1","STOP",
  115.  0
  116. };
  117.  
  118.  
  119. WRITE_HANDLER( gottlieb_speech_w )
  120. {
  121.     static int queue[100],pos;
  122.  
  123.     data ^= 255;
  124.  
  125. logerror("Votrax: intonation %d, phoneme %02x %s\n",data >> 6,data & 0x3f,PhonemeTable[data & 0x3f]);
  126.  
  127.     queue[pos++] = data & 0x3f;
  128.  
  129.     if ((data & 0x3f) == 0x3f)
  130.     {
  131. #if 0
  132.         if (pos > 1)
  133.         {
  134.             int i;
  135.             char buf[200];
  136.  
  137.             buf[0] = 0;
  138.             for (i = 0;i < pos-1;i++)
  139.             {
  140.                 if (queue[i] == 0x03 || queue[i] == 0x3e) strcat(buf," ");
  141.                 else strcat(buf,PhonemeTable[queue[i]]);
  142.             }
  143.  
  144.             usrintf_showmessage(buf);
  145.         }
  146. #endif
  147.  
  148.         pos = 0;
  149.     }
  150.  
  151.     /* generate a NMI after a while to make the CPU continue to send data */
  152.     timer_set(TIME_IN_USEC(50),0,gottlieb_nmi_generate);
  153. }
  154.  
  155. WRITE_HANDLER( gottlieb_speech_clock_DAC_w )
  156. {}
  157.  
  158.  
  159.  
  160.     /* partial decoding takes place to minimize chip count in a 6502+6532
  161.        system, so both page 0 (direct page) and 1 (stack) access the same
  162.        128-bytes ram,
  163.        either with the first 128 bytes of the page or the last 128 bytes */
  164.  
  165. unsigned char *riot_ram;
  166.  
  167. READ_HANDLER( riot_ram_r )
  168. {
  169.     return riot_ram[offset&0x7f];
  170. }
  171.  
  172. WRITE_HANDLER( riot_ram_w )
  173. {
  174.     riot_ram[offset&0x7f]=data;
  175. }
  176.  
  177. static unsigned char riot_regs[32];
  178.     /* lazy handling of the 6532's I/O, and no handling of timers at all */
  179.  
  180. READ_HANDLER( gottlieb_riot_r )
  181. {
  182.     switch (offset&0x1f) {
  183.     case 0: /* port A */
  184.         return soundlatch_r(offset) ^ 0xff;    /* invert command */
  185.     case 2: /* port B */
  186.         return 0x40;    /* say that PB6 is 1 (test SW1 not pressed) */
  187.     case 5: /* interrupt register */
  188.         return 0x40;    /* say that edge detected on PA7 */
  189.     default:
  190.         return riot_regs[offset&0x1f];
  191.     }
  192. }
  193.  
  194. WRITE_HANDLER( gottlieb_riot_w )
  195. {
  196.     riot_regs[offset&0x1f]=data;
  197. }
  198.  
  199.  
  200.  
  201.  
  202. static int psg_latch;
  203. static void *nmi_timer;
  204. static int nmi_rate;
  205. static int ym2151_port;
  206.  
  207. void gottlieb_sound_init(void)
  208. {
  209.     nmi_timer = NULL;
  210. }
  211.  
  212. READ_HANDLER( stooges_sound_input_r )
  213. {
  214.     /* bits 0-3 are probably unused (future expansion) */
  215.  
  216.     /* bits 4 & 5 are two dip switches. Unused? */
  217.  
  218.     /* bit 6 is the test switch. When 0, the CPU plays a pulsing tone. */
  219.  
  220.     /* bit 7 comes from the speech chip DATA REQUEST pin */
  221.  
  222.     return 0xc0;
  223. }
  224.  
  225. WRITE_HANDLER( stooges_8910_latch_w )
  226. {
  227.     psg_latch = data;
  228. }
  229.  
  230. /* callback for the timer */
  231. static void nmi_callback(int param)
  232. {
  233.     cpu_cause_interrupt(cpu_gettotalcpu()-1, M6502_INT_NMI);
  234. }
  235.  
  236. static WRITE_HANDLER( common_sound_control_w )
  237. {
  238.     /* Bit 0 enables and starts NMI timer */
  239.  
  240.     if (nmi_timer)
  241.     {
  242.         timer_remove(nmi_timer);
  243.         nmi_timer = 0;
  244.     }
  245.  
  246.     if (data & 0x01)
  247.     {
  248.         /* base clock is 250kHz divided by 256 */
  249.         double interval = TIME_IN_HZ(250000.0/256/(256-nmi_rate));
  250.         nmi_timer = timer_pulse(interval, 0, nmi_callback);
  251.     }
  252.  
  253.     /* Bit 1 controls a LED on the sound board. I'm not emulating it */
  254. }
  255.  
  256. WRITE_HANDLER( stooges_sound_control_w )
  257. {
  258.     static int last;
  259.  
  260.     common_sound_control_w(offset, data);
  261.  
  262.     /* bit 2 goes to 8913 BDIR pin  */
  263.     if ((last & 0x04) == 0x04 && (data & 0x04) == 0x00)
  264.     {
  265.         /* bit 3 selects which of the two 8913 to enable */
  266.         if (data & 0x08)
  267.         {
  268.             /* bit 4 goes to the 8913 BC1 pin */
  269.             if (data & 0x10)
  270.                 AY8910_control_port_0_w(0,psg_latch);
  271.             else
  272.                 AY8910_write_port_0_w(0,psg_latch);
  273.         }
  274.         else
  275.         {
  276.             /* bit 4 goes to the 8913 BC1 pin */
  277.             if (data & 0x10)
  278.                 AY8910_control_port_1_w(0,psg_latch);
  279.             else
  280.                 AY8910_write_port_1_w(0,psg_latch);
  281.         }
  282.     }
  283.  
  284.     /* bit 5 goes to the speech chip DIRECT DATA TEST pin */
  285.  
  286.     /* bit 6 = speech chip DATA PRESENT pin; high then low to make the chip read data */
  287.     if ((last & 0x40) == 0x40 && (data & 0x40) == 0x00)
  288.     {
  289.     }
  290.  
  291.     /* bit 7 goes to the speech chip RESET pin */
  292.  
  293.     last = data & 0x44;
  294. }
  295.  
  296. WRITE_HANDLER( exterm_sound_control_w )
  297. {
  298.     common_sound_control_w(offset, data);
  299.  
  300.     /* Bit 7 selects YM2151 register or data port */
  301.     ym2151_port = data & 0x80;
  302. }
  303.  
  304. WRITE_HANDLER( gottlieb_nmi_rate_w )
  305. {
  306.     nmi_rate = data;
  307. }
  308.  
  309. static void cause_dac_nmi_callback(int param)
  310. {
  311.     cpu_cause_interrupt(cpu_gettotalcpu()-2, M6502_INT_NMI);
  312. }
  313.  
  314. WRITE_HANDLER( gottlieb_cause_dac_nmi_w )
  315. {
  316.     /* make all the CPUs synchronize, and only AFTER that cause the NMI */
  317.     timer_set(TIME_NOW,0,cause_dac_nmi_callback);
  318. }
  319.  
  320. READ_HANDLER( gottlieb_cause_dac_nmi_r )
  321. {
  322.     gottlieb_cause_dac_nmi_w(offset, 0);
  323.     return 0;
  324. }
  325.  
  326. WRITE_HANDLER( exterm_ym2151_w )
  327. {
  328.     if (ym2151_port)
  329.     {
  330.         YM2151_data_port_0_w(offset, data);
  331.     }
  332.     else
  333.     {
  334.         YM2151_register_port_0_w(offset, data);
  335.     }
  336. }
  337.